import React, { useMemo, useState, useEffect } from 'react';
import { filter_row, loc_str, FindBarBase, useCmd, ErrView, WaitUmd,
    save_data, uDb, obj_str, useHigh, MainView, Btn, GridTable, cline, urlTb, is_empty, for_obj, obj_empty, loc } from 'sui';
import { get_init, load_station, cell_row } from './cmd';
import { utc_offset } from 'cache';

const TraceView = ({ mod, sideopen }) => {
    const [cell, setCell] = useState(null);
    const [col, setCol] = useState();
    const [row, setRow] = useState();
    const [station, setStation] = useState();
    const [para, setPara] = useState();
    const [mtype, setType] = useState(null);
    const [main, setMain] = useState(null);
    const [opt_find, optFind] = useState();
    const umd = useCmd(null, "trace");
    const [high] = useHigh(140, 100);

    useEffect(() => get_init(optFind), []);

    useEffect(() => {
        setCell(null);
        setType(null);
        setMain(null);
        setRow(null);

        uDb(null, "file/get/cell",
            {
                line: cline(),
                sn: mod,
            },
            r => {
                const ret = [];
                const para = r["para"];
                if (para) {
                    para.forEach(d => ret.push({id: d.sn, des: d.name}));
                }

                const sn = obj_str(r, "sn");
                urlTb(null, "field", {n: sn}, t => setType(t[sn]), e => setType(null));

                setCell(r);
                setPara(ret);
            },
            e => setCell(null));

        load_station(setStation);
    }, [mod]);

    useEffect(() => {
        if (obj_empty(cell)) {
            return;
        }

        const para = cell["para"];

        if (is_empty(para)) {
            return;
        }

        const col = [
            {name: loc("l_193"), key: 'index', width: 70, frozen: true},
        ];

        para.forEach(d => col.push({name: d.name, key: d.sn, width: 170}));

        if (col.length > 3) {
            col[0]["frozen"] = true;
            col[1]["frozen"] = true;
        }

        setCol(col);
    }, [cell]);

    useEffect(() => {
        if (obj_empty(main) || !cell) {
            return;
        }

        const tmp = main.data;
        if (is_empty(tmp)) {
            return;
        }

        let row = cell_row(tmp);

        setRow(row);
    }, [main, cell]);

    const get_val = (k, v) => {
        if (is_empty(mtype)) {
            return v;
        }

        const f = mtype.find(d => d === k);
        if (!f) {
            return v;
        }

        if (v === "true") {
            return true;
        }

        if (v === "false") {
            return false;
        }

        if (v.lastIndexOf(".") >= 0) {
            return parseFloat(v);
        }

        return parseInt(v, 10);
    };

    const hfind = (value) => {
        const opt = [];
        const utc = utc_offset();

        for_obj(value, (k, v) => {
            if (k === "t_start" || k === "t_end") {
                return;
            }

            if (!v) {
                return;
            }

            if (k === "time") {
                opt.push({ge: "time", v: loc_str(value["t_start"]), utc: utc});
                opt.push({le: "time", v: loc_str(value["t_end"]), utc: utc});
                return;
            }

            opt.push({eq: k, v: get_val(k, v)});
        });

        if (is_empty(opt)) {
            alert(loc("l_307"));
            return;
        }

        opt.push({eq: "line", v: cline()});

        umd.startWait();

        const cmd = {
            n: cell.sn,
            obj: "*",
            opt: {desc: true, and: opt}
        };

        urlTb(null, "get", cmd,
            r => {
                const data = r[cell.sn]["data"];

                setMain({
                    data: data,
                });

                umd.endWait();
            },
            e => {
                setMain({err: true});
                umd.endWait();
            });
    };

    const filteredRows = useMemo(() => {
        if (is_empty(row) || is_empty(col)) {
            return null;
        }

        const lst = col.map(d => d.key);

        return filter_row(row, lst, umd.filter);
    }, [col, row, umd.filter]);

    const TraceTable = () => {
        if (!obj_empty(main) && main.err) {
            return <ErrView err={loc("l_316")}/>;
        }

        if (is_empty(col)) {
            return null;
        }

        return <GridTable col={col} row={filteredRows} high={high - 50}/>;
    };

    const hExport = () => {
        save_data(row, col, `${cell.name}_data`, umd);
    };

    const Right = () => {
        if (!cell) {
            return null;
        }

        return (
            <div className="inline-flex items-center">
                <Btn hcmd={hExport} className="ml-4">{loc("l_298")}</Btn>
            </div>
        );
    };

    const Left = () => {
        if (!cell) {
            return null;
        }

        return <div>{`${cell.sn} ( ${cell.name} )`}</div>
    };

    const hclear = () => get_init(optFind);

    const getCtl = () => {
        const getLst = () => {
            if (obj_empty(station)) {
                return null;
            }

            const ret = [];
            for_obj(station, (k, v) => ret.push({id: k, sn: k, name: v}));
            return ret;
        };

        let psn_name = loc("l_152");
        if (col) {
            const f = col.find(d => d.key === "psn");
            if (f) {
                psn_name = f.name;
            }
        }

        return {
            ctl: [
                {sn: "psn", name: psn_name},
                {sn: "wsn", name: loc("l_100"), ctl: "IkFind", lst: getLst()},
                {sn: "time", name: loc("l_308"), ctl: "IkFindDate", start: "t_start", end: "t_end"},
            ],
            para: para,
        };
    };

    return (
        <MainView>
            <FindBarBase left={<Left/>} right={<Right/>} hcmd={hfind} data={getCtl()} hclear={hclear} cur={opt_find} hfilter={umd.setFilter}/>
            <TraceTable/>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {TraceView};
